

/*
 * GPS_QieHuan.c
 *
 *  Created on: 2015-10-8
 *      Author: WFL
 *
 *  Functions are wrote for GPSDataHandler Task
 */

#include "GPS_QieHuan.h"
#include "GPS_Location_Handle.h"
#include "XFlash.h"
#include "GPS_SatelliteData.h"
#include "GPS_RoadLockHandle.h"
#include "GPS_PublicPositionData.h"
#include "GPS_PRE_NXT_ST.h"

extern volatile MY_INFO MyInfo;
extern DATA_BASE_INFO DataBase;

/*
 * search QieHuan Database
 * the situation to QieHuan road should be confirm.
 * 1) inside/outside a station
 * 2) road locked
 * 3) isn't the invalid previous station
 * 4) the entering moment only
 */
#pragma CODE_SECTION(SearchQieHuanDatabase, "FuncsMap2H0SARam")
void SearchQieHuanDatabase()
{
	Uns i;
	QH_INFO qiehuan_buf;
	volatile LgUns offset;

	offset=MyInfo.DBQieHuanOffset;
	if(CurrGpsInfo.State!='A')
		return;
	for(i=0;i<DataBase.QieHuanCnt;i++)
	{
		S29G_FlashRead(&qiehuan_buf.QH_ID,offset,32);
		GPS_ConvertLonLat(&qiehuan_buf.Lon0_1,16,&qiehuan_buf.Longi,&qiehuan_buf.Lati);
		if(InAreaCheck(
						CurrGpsInfo.Longi,CurrGpsInfo.Lati,
						qiehuan_buf.Longi,qiehuan_buf.Lati,
						qiehuan_buf.L_Rht_lon,qiehuan_buf.L_Rht_lat,		//lower right
						qiehuan_buf.L_Rht_lon,qiehuan_buf.U_Lft_lat,		//upper right
						qiehuan_buf.U_Lft_lon,qiehuan_buf.U_Lft_lat,		//upper left
						qiehuan_buf.U_Lft_lon,qiehuan_buf.L_Rht_lat))		//lower left
		{
			EnterQieHuanHandler(i+1,&qiehuan_buf);
			return;
		}
		offset+=32;
	}
	MyInfo.CurrQieHuanIndex=0;
	return;
}

//things to do when entering a new QieHuan for the first time
#pragma CODE_SECTION(EnterQieHuanHandler, "FuncsMap2H0SARam")
void EnterQieHuanHandler(Uns index,QH_INFO* qiehuan_buf)
{
	Uns i;
	LgUns lastST;
	LgUns invalidST[8];

	//if is the first time enter this QieHuan area.
	if(MyInfo.CurrQieHuanIndex==index)
	{
		return;
	}
	MyInfo.CurrQieHuanIndex=index;

	//road lock only.
	if(!MyInfo.RoadLocked)
	{
		return;
	}

	//not in a station this moment.
	if(MyInfo.LockedRoadIndex!=qiehuan_buf->Rd_Index[0]&&MyInfo.LockedRoadIndex!=qiehuan_buf->Rd_Index[1])
	{
		return;
	}

	//if no PREV_ST_1 station, return.
	//for the situation of newly selecting a line(clean PREV_ST)
	if(PRE_NXT_ST_Info[PREV_ST_1].ST_Index==0)
	{
		return;
	}

	if(PRE_NXT_ST_Info[PREV_ST_1].RD_Index!=MyInfo.LockedRoadIndex)
	{
		return;
	}

	//check invalid station.
	lastST=PRE_NXT_ST_Info[PREV_ST_1].ST_Index;
	invalidST[0]=qiehuan_buf->InvalidSTIndex[0]+((LgUns)qiehuan_buf->InvalidSTIndex[1]<<16);
	invalidST[1]=qiehuan_buf->InvalidSTIndex[2]+((LgUns)qiehuan_buf->InvalidSTIndex[3]<<16);
	invalidST[2]=qiehuan_buf->InvalidSTIndex[4]+((LgUns)qiehuan_buf->InvalidSTIndex[5]<<16);
	invalidST[3]=qiehuan_buf->InvalidSTIndex[6]+((LgUns)qiehuan_buf->InvalidSTIndex[7]<<16);
	invalidST[4]=qiehuan_buf->InvalidSTIndex[8]+((LgUns)qiehuan_buf->InvalidSTIndex[9]<<16);
	invalidST[5]=qiehuan_buf->InvalidSTIndex[10]+((LgUns)qiehuan_buf->InvalidSTIndex[11]<<16);
	invalidST[6]=qiehuan_buf->InvalidSTIndex[12]+((LgUns)qiehuan_buf->InvalidSTIndex[13]<<16);
	invalidST[7]=qiehuan_buf->InvalidSTIndex[14]+((LgUns)qiehuan_buf->InvalidSTIndex[15]<<16);
	for(i=0;i<8;i++)
	{
		if(invalidST[i]==lastST)
			return;
	}

	if(MyInfo.LockedRoadIndex==qiehuan_buf->Rd_Index[0])
	{
		RoadLockTo(qiehuan_buf->Rd_Index[1]);
	}
	else
	{
		RoadLockTo(qiehuan_buf->Rd_Index[0]);
	}

	//refresh ST_ON_RD
	Refresh_ST_ON_RD((Uns)MyInfo.LockedRoadIndex);
	//refresh road information
	RefreshRoadInfo(MyInfo.LockedRoadIndex);
}

///////////////////////////////////////////////////////////////////////////
//										END
///////////////////////////////////////////////////////////////////////////
